// 验证信号量在生产者-消费者模型中的应用

#include <gtest/gtest.h>
#include <semaphore.h>
#include <queue>
#include <thread>
#include <mutex>

std::queue<int> buffer;
std::counting_semaphore<10> empty_slots(10); // 最大缓冲区大小
std::counting_semaphore<0> full_slots(0);    // 初始缓冲区为空
std::mutex mtx;

void producer(int id, int items) {
    for (int i = 0; i < items; ++i) {
        empty_slots.acquire();  // 等待空槽
        std::lock_guard<std::mutex> lock(mtx);
        buffer.push(i);
        full_slots.release();  // 增加满槽计数
    }
}

void consumer(int id, int items, std::vector<int>& consumed_items) {
    for (int i = 0; i < items; ++i) {
        full_slots.acquire();  // 等待满槽
        std::lock_guard<std::mutex> lock(mtx);
        if (!buffer.empty()) {
            consumed_items.push_back(buffer.front());
            buffer.pop();
        }
        empty_slots.release();  // 增加空槽计数
    }
}

TEST(SemaphoreTest, ProducerConsumer) {
    const int total_items = 10;
    const int num_producers = 2;
    const int num_consumers = 2;

    std::vector<int> consumed_items;
    std::thread producers[num_producers];
    std::thread consumers[num_consumers];

    for (int i = 0; i < num_producers; ++i) {
        producers[i] = std::thread(producer, i, total_items / num_producers);
    }

    for (int i = 0; i < num_consumers; ++i) {
        consumers[i] = std::thread(consumer, i, total_items / num_consumers, std::ref(consumed_items));
    }

    for (auto& t : producers) t.join();
    for (auto& t : consumers) t.join();

    EXPECT_EQ(consumed_items.size(), total_items);
}